/*
 * Copyright 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.jp.app.client.ui;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.ListDataProvider;
import com.google.web.bindery.autobean.shared.AutoBean;
import com.google.web.bindery.autobean.shared.AutoBeanCodex;
import com.jp.app.client.Test.BookAutoBeanFactory;
import com.jp.app.client.model.Book;
import com.jp.app.client.model.RecordResult;

/**
 * The data source for contact information used in the sample.
 */
public class ContactDatabase {

  private RequestBuilder getBooksReq;
  private RequestBuilder saveBooksReq;	
  private BookAutoBeanFactory factory;
  
  /**
   * The constants used in this Content Widget.
   */
  static interface DatabaseConstants extends Constants {
    String[] contactDatabaseCategories();
  }

  /**
   * The singleton instance of the database.
   */
  private static ContactDatabase instance;

  /**
   * Get the singleton instance of the contact database.
   * 
   * @return the singleton instance
   */
  public static ContactDatabase get() {
    if (instance == null) {
      instance = new ContactDatabase();
    }
    return instance;
  }

  /**
   * The provider that holds the list of contacts in the database.
   */
  private ListDataProvider<Book> dataProvider = new ListDataProvider<Book>();

  /**
   * Construct a new contact database.
   */
  private ContactDatabase() {
    factory = GWT.create(BookAutoBeanFactory.class);
    createRequests();
    getBooks();
  }

  private void createRequests(){
	  getBooksReq = new RequestBuilder(RequestBuilder.GET, "/book/getBooks.json");
	  
	  saveBooksReq = new RequestBuilder(RequestBuilder.POST, "/book/create-book.json");
	  saveBooksReq.setHeader("Content-Type","application/x-www-form-urlencoded");
  }
  
  private void getBooks(){
	  getBooksReq.setCallback(new RequestCallback() {

  		@Override
  		public void onResponseReceived(Request request, Response response) {
  			RecordResult result = null;
  			if(response.getText() != null){
  				AutoBean<RecordResult> bean = AutoBeanCodex.decode(factory, RecordResult.class, response.getText());
  				result = bean.as();
  				List<Book> contacts = dataProvider.getList();
  			    
  				for (Book book : result.getRecords()) {
  					contacts.add(book);
				}
  				
  			}
  			
  		}

  		@Override
  		public void onError(Request request,	Throwable exception) {
  			// TODO Auto-generated method stub
  		}
  	         
  	    });
  	  
  	  try {
  		  getBooksReq.send();
  	    }
  	  catch (Exception e){
  	       e.printStackTrace();
  	    }
	  
  }
  
  
  /**
   * Add a new contact.
   * 
   * @param book the contact to add.
   */
  public void addContact(Book book) {
    List<Book> contacts = dataProvider.getList();
    // Remove the contact first so we don't add a duplicate.
    contacts.remove(book);
    contacts.add(book);
  }

  /**
   * Add a display to the database. The current range of interest of the display
   * will be populated with data.
   * 
   * @param display a {@Link HasData}.
   */
  public void addDataDisplay(HasData<Book> display) {
    dataProvider.addDataDisplay(display);
  }

  public ListDataProvider<Book> getDataProvider() {
    return dataProvider;
  }

  /**
   * Refresh all displays.
   */
  public void refreshDisplays() {
    dataProvider.refresh();
  }

}
